#include<stdio.h>
#include<stdlib.h>
#include"double_link.h"
#include<string.h>


int llist_insert(LList_st *,const void *,enum way);

void *llist_find(LList_st *,const void *,find_op);

int llist_fcget(LList_st *,const void *,find_op,void *);

int llist_delete(LList_st *,const void *,find_op);

int llist_display(LList_st *,llist_op);






LList_st *llist_create(int initsize)
{
	LList_st *me = NULL;
	me = malloc(sizeof(*me));
	if(me == NULL)
		return NULL;
	me->size = initsize;
	me->head.prev = me->head.next = &me->head;
	me->insert = llist_insert;
	me->find = llist_find;
	me->fcget = llist_fcget;
	me->delete_ = llist_delete;
	me->display = llist_display;
	return me;
}




int llist_insert(LList_st *ptr,const void *data,enum way mode)
{
	llist *newnode;
	newnode = malloc(sizeof(*newnode)+ptr->size-4);
	if(newnode == NULL)
		return -1;
	memcpy(newnode->data,data,ptr->size);
	if(mode == FRONT)
	{
		newnode->prev = &ptr->head;
		newnode->next = ptr->head.next;
	}
	else	if(mode == BEHIND)
	{
		newnode->prev = ptr->head.prev;
		newnode->next = &ptr->head;
	}
	else
	{
		return -3;
	}
	newnode->prev->next = newnode;
	newnode->next->prev = newnode;
	return 0;
}
static llist *find_(LList_st *ptr,const void *key,find_op op)
{
	llist *p;
	for(p = ptr->head.next;p != &ptr->head;p = p->next)
	{
		if(op(p->data,key) == 0)
			break;
	}
	return p;

}

void *llist_find(LList_st *ptr,const void *key,find_op op)
{
	llist *p;
	p = find_(ptr,key,op);
	if(p == &ptr->head)
		return NULL;
	return p->data;
}

int llist_fcget(LList_st *me,const void *key,find_op op,void *data)
{
	llist *p;
	p = find_(me,key,op);
	if(p == &me->head)
		return -1;
	p->prev->next = p->next;
	p->next->prev = p->prev;
	if(data != NULL)
		memcpy(data,p->data,me->size);
	free(p);

}

int llist_delete(LList_st *me,const void *key,find_op op)
{
	llist *p;
	p = find_(me,key,op);
	if(p == &me->head)
		return -1;
	p->prev->next = p->next;
	p->next->prev = p->prev;
	free(p);
	return 0;	
}
int llist_display(LList_st *me,llist_op op)
{
	llist *p;
	for(p = me->head.next;p != &me->head;p = p->next)
		op(p->data);
	return 0;
}

void llist_distory(LList_st *me)
{
	llist *p,*q;
	for(p = me->head.next;p != &me->head;p = q)
	{
		q = p->next;
		free(p);
	}
	free(me);
}
